/**
 * 作者: wgx
 * 日期: 2024-09-25 16:26:20
 * 备注: 用户信息表（字段不能设置默认值，代码里设置）
 */
package com.motu.monstercity.server.game.userdata;

import com.motu.data.UserLoginDevice;
import com.motu.monstercity.protocol.Common;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.bag.ItemId;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.system.UserExp;
import com.motu.monstercity.server.game.log.MotuLogManager;
import com.motu.monstercity.server.game.log.ThinkingDataManager;
import com.motu.monstercity.server.game.logic.GameDataManager;
import com.motu.monstercity.server.game.logic.GameUser;
import com.motu.monstercity.server.game.logic.MainTaskManager;
import com.motu.monstercity.server.game.logic.RankActManager;
import com.motu.vertx.module.utility.logsdk.AdjustManager;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.json.JsonObject;

public class UserInfo extends UserInfoModel {
    public UserInfo() {
        super();
    }

    public void reset() {
        boolean updated = false;
        if (getLevel() == 0) {
            super.putLevel(1);// 市政等级(初始1级)
            updated = true;
        }
        if (recoverEnergy()) {
            updated = true;
        }
        if (Tool.isEmpty(getUserName())) {
            super.putUserName(AllParam.INIT_NAME_USER);
            updated = true;
        }
        if (updated) {
            update();
        }
    }

    public Common.PBUserInfo.Builder takeInitBuilder() {
        Common.PBUserInfo.Builder sb = super.takeInitBuilder();
        String code = Long.toHexString(getId());
        sb.setInviteCode(code);
        return sb;
    }

    public void putVip(PBUserData.Builder pbUserData, byte vip) {
        if (this.vip == vip) {
            return;// 没有变更
        }
        super.putVip(vip);
        MainTaskManager.updateTaskProgress(pbUserData, this, MainTaskConstant.TASK_TYPE_25, (long)vip);
        RankActManager.updateTaskProgress(pbUserData, this, MainTaskConstant.TASK_TYPE_25, (long)vip);
        GameUser.updateUserShow(this, null);// 更新用户展示数据
    }

    public boolean recoverEnergy() {
        UserExp userExp = GameDataManager.getUserExp(level);
        if (userExp == null) {
            return false;
        }
        if (energy >= userExp.getTravelNum()) { // 达到上限体力
            return false;
        }
        long curTime = TimeUtils.getCurTime();
        if (energyRecoverTime == 0) {
            putEnergy(userExp.getTravelNum());
            putEnergyRecoverTime(curTime);
            return true;
        }
        long deltaTime = curTime - energyRecoverTime;
        long recoveryTime = (long) AllParam.PATROL_LOCATION_PHYSICAL_RECOVERY_TAKES_TIME * TimeUtils.MINUTE;
        if (deltaTime < recoveryTime) {
            return false;
        }
        int deltaEnergy = (int) (deltaTime / recoveryTime);
        long newRecoveryTime = energyRecoverTime;
        int newEnergy = energy;
        newEnergy += deltaEnergy;
        if (newEnergy >= userExp.getTravelNum()) {
            newEnergy = userExp.getTravelNum();
            newRecoveryTime = curTime;
        } else {
            newRecoveryTime += deltaEnergy * recoveryTime;
        }
        putEnergy(newEnergy);
        putEnergyRecoverTime(newRecoveryTime);
        return true;
    }

    // 记录日志并增加钻石数量
    public void addDiamond(int num, Object... params) {
        int balance = getDiamond();// 当前余额
        long dbid = 0;
        MotuLogManager.logItemIncome(this, ItemId.DIAMOND, dbid, balance, num, params);
        super.addDiamond(num);
    }

    // 扣除钻石
    public void subDiamond(int num, Object... params) {
        int balance = getDiamond();// 当前余额
        if (num > balance) {
            num = balance;// 全部扣除
        }
        long dbid = 0;
        MotuLogManager.logItemConsume(this, ItemId.DIAMOND, dbid, balance, num, params);
        super.addDiamond(-num);
    }

    // 记录日志并增加金币数量
    public void addGold(long num, Object... params) {
        long balance = getGold();// 当前余额
        long dbid = 0;
        UserThinkingData userThinkingData = GameUser.getUserThinkingData(getId());
        userThinkingData.addCoinGet(num);
        userThinkingData.update();
        MotuLogManager.logItemIncome(this, ItemId.GOLD, dbid, balance, num, params);
        super.addGold(num);
    }

    // 扣除金币
    public void subGold(long num, Object... params) {
        long balance = getGold();// 当前余额
        if (num > balance || num < 0) {
            return;// 余额不足
        }
        long dbid = 0;
        UserThinkingData userThinkingData = GameUser.getUserThinkingData(getId());
        userThinkingData.addCoinCost(num);
        userThinkingData.update();
        MotuLogManager.logItemConsume(this, ItemId.GOLD, dbid, balance, num, params);
        super.addGold(-num);
    }

    // 记录日志并增加
    public void addRepu(PBUserData.Builder pbUserData, UserInfo userInfo, int num, Object... params) {
        long balance = getRepu();// 当前余额
        long dbid = 0;
        MotuLogManager.logItemIncome(this, ItemId.USER_REPU, dbid, balance, num, params);
        super.addRepu(num);
        if (num > 0) {
            MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_245, getRepu());// 更新主线任务,成就,日常任务的进度
        }
    }

    // 记录日志并增加体力值
    public void addEnergy(int num, Object... params) {
        int balance = getEnergy();// 当前余额
        long dbid = 0;
        MotuLogManager.logItemIncome(this, ItemId.ENERGY, dbid, balance, num, params);
        super.addEnergy(num);
    }

    // 扣除体力值
    public void subEnergy(int num, Object... params) {
        int balance = getEnergy();// 当前余额
        if (num > balance) {
            return;// 余额不足
        }
        long dbid = 0;
        MotuLogManager.logItemConsume(this, ItemId.ENERGY, dbid, balance, num, params);
        super.addEnergy(-num);
    }

    public JsonObject update(PBUserData.Builder pbUserData) {
        if (pbUserData != null) {
            ProtoDataUtils.updatePBUserData(pbUserData, this);
        }
        return super.update();
    }

    /**
     * 增加vip积分
     * @param price
     * @param params
     */
    public void addVipScore(int price, Object... params) {
        if (params.length > 0) {
            MotuLogManager.logItemIncome(this, ItemId.VIP_SCORE, 0, getVipScore(), price, params);
        }
        super.addVipScore(price);
    }

    /**
     * 增加免费vip积分
     * @param price
     * @param params
     */
    public void addFreeVipScore(int price, Object... params) {
        if (params.length > 0) {
            MotuLogManager.logItemIncome(this, ItemId.FREE_VIP_SCORE, 0, getFreeVipScore(), price, params);
        }
        super.addFreeVipScore(price);
    }

    // 玩家升级事件
    public void putLevel(int level) {
        if (getLevel() == level) {
            return;// 没有变更
        }

        int curLevel = getLevel();
        UserLoginDevice userLoginDevice = GameUser.getUserLoginDevice(getId());// 用户登录设备信息
        for (int i=curLevel+1; i<=level; i++) {// 如从1级升到3级,只发2,3级的数据
            AdjustManager.sendEvent(getId(), userLoginDevice, AdjustManager.LEVEL, i);// adjust level事件
        }
        // 数数用户等级升级事件
        ThinkingDataManager.pushUserLevelUpEvent(this , ThinkingDataManager.EVENT_LEVEL_UP_LEVEL, curLevel, level);

        super.putLevel(level);
        GameUser.updateUserShow(this, null);// 更新用户展示数据
    }

    public void putUserName(String userName) {
        if (this.userName.equals(userName)) {
            return;
        }
        super.putUserName(userName);
        GameUser.updateUserShow(this, null);// 更新用户展示数据
    }

    public void putIcon(String icon) {
        if (this.icon.equals(icon)) {
            return;
        }
        super.putIcon(icon);
        GameUser.updateUserShow(this, null);// 更新用户展示数据
    }

    public void putIconFrame(int iconFrame) {
        if (this.iconFrame == iconFrame) {
            return;
        }
        super.putIconFrame(iconFrame);
        GameUser.updateUserShow(this, null);// 更新用户展示数据
    }

    public void putTitleId(int titleId) {
        if (this.titleId == titleId) {
            return;
        }
        super.putTitleId(titleId);
        GameUser.updateUserShow(this, null);// 更新用户展示数据
    }

    public void putBubbleId(int bubbleId) {
        if (this.bubbleId == bubbleId) {
            return;
        }
        super.putBubbleId(bubbleId);
        GameUser.updateUserShow(this, null);// 更新用户展示数据
    }
}
